From: Keir Fraser Date: Tue, 18 Nov 2008 11:16:36 +0000 (+0000) Subject: x86, hvm: Implement interrupt routing to least priority processor. X-Git-Tag: archive/raspbian/4.8.0-1+rpi1~1^2~14043^2~24 X-Git-Url: https://dgit.raspbian.org/%22http://www.example.com/cgi/success//%22http:/www.example.com/cgi/success/?a=commitdiff_plain;h=5f8902540cff4f5a69218f3cdd04caf5a0028ee8;p=xen.git x86, hvm: Implement interrupt routing to least priority processor. Instead of round robin the vcpu with the lowest processor priority is selected for the interrupt. If multiple vcpus share the same low priority then interrupts are distributed between those round robin. Signed-off-by: Juergen Gross Signed-off-by: Keir Fraser --- diff --git a/xen/arch/x86/hvm/vioapic.c b/xen/arch/x86/hvm/vioapic.c index 7250de3a7d..7f63699ab2 100644 --- a/xen/arch/x86/hvm/vioapic.c +++ b/xen/arch/x86/hvm/vioapic.c @@ -344,8 +344,8 @@ static void vioapic_deliver(struct hvm_hw_vioapic *vioapic, int irq) } else #endif - target = apic_round_robin(vioapic_domain(vioapic), - vector, deliver_bitmask); + target = apic_lowest_prio(vioapic_domain(vioapic), + deliver_bitmask); if ( target != NULL ) { ioapic_inj_irq(vioapic, target, vector, trig_mode, delivery_mode); diff --git a/xen/arch/x86/hvm/vlapic.c b/xen/arch/x86/hvm/vlapic.c index d201af2848..68e9b27632 100644 --- a/xen/arch/x86/hvm/vlapic.c +++ b/xen/arch/x86/hvm/vlapic.c @@ -377,26 +377,30 @@ static int vlapic_accept_irq(struct vcpu *v, int delivery_mode, } /* This function is used by both ioapic and lapic.The bitmap is for vcpu_id. */ -struct vlapic *apic_round_robin( - struct domain *d, uint8_t vector, uint32_t bitmap) +struct vlapic *apic_lowest_prio(struct domain *d, uint32_t bitmap) { - int next, old; - struct vlapic *target = NULL; + int old = d->arch.hvm_domain.irq.round_robin_prev_vcpu; + uint32_t ppr, target_ppr = UINT_MAX; + struct vlapic *vlapic, *target = NULL; + struct vcpu *v; - old = next = d->arch.hvm_domain.irq.round_robin_prev_vcpu; + if ( unlikely((v = d->vcpu[old]) == NULL) ) + return NULL; do { - if ( ++next == MAX_VIRT_CPUS ) - next = 0; - if ( (d->vcpu[next] == NULL) || !test_bit(next, &bitmap) ) - continue; - target = vcpu_vlapic(d->vcpu[next]); - if ( vlapic_enabled(target) ) - break; - target = NULL; - } while ( next != old ); + v = v->next_in_list ? : d->vcpu[0]; + vlapic = vcpu_vlapic(v); + if ( test_bit(v->vcpu_id, &bitmap) && vlapic_enabled(vlapic) && + ((ppr = vlapic_get_ppr(vlapic)) < target_ppr) ) + { + target = vlapic; + target_ppr = ppr; + } + } while ( v->vcpu_id != old ); - d->arch.hvm_domain.irq.round_robin_prev_vcpu = next; + if ( target != NULL ) + d->arch.hvm_domain.irq.round_robin_prev_vcpu = + vlapic_vcpu(target)->vcpu_id; return target; } @@ -456,7 +460,7 @@ int vlapic_ipi( if ( delivery_mode == APIC_DM_LOWEST ) { - target = apic_round_robin(vlapic_domain(v), vector, lpr_map); + target = apic_lowest_prio(vlapic_domain(v), lpr_map); if ( target != NULL ) rc = vlapic_accept_irq(vlapic_vcpu(target), delivery_mode, vector, level, trig_mode); diff --git a/xen/arch/x86/hvm/vmsi.c b/xen/arch/x86/hvm/vmsi.c index 6eefb61bfa..cc9e9adde5 100644 --- a/xen/arch/x86/hvm/vmsi.c +++ b/xen/arch/x86/hvm/vmsi.c @@ -152,7 +152,7 @@ int vmsi_deliver(struct domain *d, int pirq) { case dest_LowestPrio: { - target = apic_round_robin(d, vector, deliver_bitmask); + target = apic_lowest_prio(d, deliver_bitmask); if ( target != NULL ) vmsi_inj_irq(d, target, vector, trig_mode, delivery_mode); else diff --git a/xen/include/asm-x86/hvm/vlapic.h b/xen/include/asm-x86/hvm/vlapic.h index 3f34e47950..8c36ed5a00 100644 --- a/xen/include/asm-x86/hvm/vlapic.h +++ b/xen/include/asm-x86/hvm/vlapic.h @@ -93,8 +93,7 @@ void vlapic_msr_set(struct vlapic *vlapic, uint64_t value); int vlapic_accept_pic_intr(struct vcpu *v); -struct vlapic *apic_round_robin( - struct domain *d, uint8_t vector, uint32_t bitmap); +struct vlapic *apic_lowest_prio(struct domain *d, uint32_t bitmap); int vlapic_match_logical_addr(struct vlapic *vlapic, uint8_t mda);